package com.videri.match.client;

import com.videri.match.client.MatchSink;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.TreeListener;
import java.util.*;

/**
 * This sink will allow for users to choose from a list
 * of matching games from a variety of categories.
 * @author Michael Bauer
 *
 */
public class VideriChooser extends MatchSink implements TreeListener {

	/**
	 * Initialize the sink and return the info associated with it
	 * @return the MatchSinkInfo associated with this sink
	 */
	public static MatchSinkInfo init() {
		return new MatchSinkInfo("Choose a Matching") {
			public MatchSink createInstance(){
				return new VideriChooser();
			}
			
			public String getColor(){
				return "#418EBC";
			}
		};
	}
	
	private VerticalPanel myChooserPanel = new VerticalPanel();
	private Category[] myCategories;
	private Matching myMatching;
	private VideriMatchSink mySink;
	
	/**
	 * Create a new chooser sink
	 */
	public VideriChooser(){
		initWidget(myChooserPanel);
		initialize();
	}
	
	private void initialize(){
		VideriMatchServiceAsync videriServices = (VideriMatchServiceAsync)GWT.create(VideriMatchService.class);
		  ServiceDefTarget endpoint = (ServiceDefTarget) videriServices;
		  String moduleRelativeURL = GWT.getModuleBaseURL()+"matching";
		  endpoint.setServiceEntryPoint(moduleRelativeURL);
		AsyncCallback callback = new AsyncCallback() {                
			public void onSuccess(Object result) {
				myChooserPanel.clear();
				myCategories = (Category[])result;
				Iterator a = myCategories[0].getMatchingNames().iterator();
				displayOptions();
			}                
			public void onFailure(Throwable caught) {                    
				System.err.println("There was an error reaching the server!");
			}            
		};
		videriServices.getAllCategories(10, callback);
	}
	
	private void displayOptions(){
		Tree t = new Tree();
		for(int i=0; i<myCategories.length; i++){
			t.addItem(displayCategory(myCategories[i]));
		}
		t.addTreeListener(this);
		myChooserPanel.add(t);
	}
	
	private TreeItem displayCategory(Category c){
		TreeItem ret = new TreeItem(c.getCategoryName());
		Set names = c.getMatchingNames();
		Iterator it = names.iterator();
		while(it.hasNext()){
			ret.addItem(new TreeItem((String)it.next()));
		}
		return ret;
	}

	public void onTreeItemSelected(TreeItem item) {
		if(item.getWidget()==null){
			//Begin GWT Black Magic here!!!
			VideriMatchServiceAsync videriServices = (VideriMatchServiceAsync)GWT.create(VideriMatchService.class);
			  ServiceDefTarget endpoint = (ServiceDefTarget) videriServices;
			  String moduleRelativeURL = GWT.getModuleBaseURL()+"matching";
			  endpoint.setServiceEntryPoint(moduleRelativeURL);
			
			AsyncCallback callback = new AsyncCallback() {
				public void onSuccess(Object result){
					myMatching = (Matching)result;
					mySink.doneChoosing(myMatching);
				}
				public void onFailure(Throwable caught){
					System.err.println("Error retreiving matching from server!");
				}
			};
			videriServices.getMatching(item.getText(),false,callback);
		}
	}

	public void onTreeItemStateChanged(TreeItem arg0) {
				
	}
	
	/**
	 * This method is used by the VideriMatchSink class
	 * to pass a reference to itself.  This allows the chooser
	 * to tell the MatchSink when a user has selected a game to 
	 * play and which game should be displayed.
	 * @param sink the VideriMatchSink that uses this sink
	 */
	public void setSink(VideriMatchSink sink){
		mySink=sink;
	}
	
	public void onShow(){
		initialize();
	}
}
